package com.dikeleakagedetection.myapplication.ui.dataMonitor

import android.graphics.Bitmap
import android.graphics.Color
import android.os.Bundle
import android.util.Log

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup

import android.widget.Toast
import androidx.fragment.app.Fragment

import androidx.lifecycle.ViewModelProvider
import com.clj.fastble.BleManager
import com.clj.fastble.callback.BleNotifyCallback
import com.clj.fastble.exception.BleException
import com.clj.fastble.utils.HexUtil
import com.dikeleakagedetection.myapplication.DikeLeakageDetectionApp
import com.dikeleakagedetection.myapplication.databinding.FragDataMonitorBinding

import com.dikeleakagedetection.myapplication.logic.dao.AppDatabase
import com.dikeleakagedetection.myapplication.logic.dao.Dot
import com.dikeleakagedetection.myapplication.logic.dao.Tablet
import com.dikeleakagedetection.myapplication.utils.*


import kotlin.concurrent.thread


class DataMonitorFragment : Fragment() {

    private lateinit var dataMonitorViewModel: DataMonitorViewModel
    private lateinit var binding: FragDataMonitorBinding

    //初始化一个Tablet变量
    private var tablet: Tablet? = null

    //初始化三个Dot变量，分别为当前点、上一个点、和基准点
    private var currDot: Dot? = null
    private var prevDot: Dot? = null
    private var baseDot: Dot? = null

    //数据库Dao对象及相关对象
    private val dotDao by lazy {
        AppDatabase.getDatabase(DikeLeakageDetectionApp.context).dotDao()
    }
    private val tabletDao by lazy {
        AppDatabase.getDatabase(DikeLeakageDetectionApp.context).tabletDao()
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        dataMonitorViewModel = ViewModelProvider(this).get(DataMonitorViewModel::class.java)
        binding = FragDataMonitorBinding.inflate(inflater, container, false)
        val view = binding.root

        //点击选择工程，选择一个已有的工程载入
        binding.lyInfoFragDataMonitor.btnSelectTabletFragDataMonitor.setOnClickListener {
            val dialog = SelectTabletDialogFragment()
            dialog.showNow(requireActivity().supportFragmentManager, "SelectTabletDialogFragment")
            dialog.setClickCallBack(object : SelectTabletDialogFragment.ClickCallBack {
                override fun clickConfirm(tabletId: Long) {
                    thread {
                        tablet = tabletDao.loadTabletById(tabletId)
                        activity?.runOnUiThread {
                            showTabletInfo()
                        }
                    }
                }
            })
        }

        //点击新建工程，得到弹窗，设置新建表的相关属性，并新建一个表
        binding.lyInfoFragDataMonitor.btnNewTabletFragDataMonitor.setOnClickListener {
            val dialog = NewTabletDialogFragment()
            dialog.showNow(requireActivity().supportFragmentManager, "NewTabletDialogFragment")
            dialog.setClickCallBack(object : NewTabletDialogFragment.ClickCallBack {
                override fun clickConfirm(date: String, place: String, length: Double, width: Double, tempBitmap: Bitmap) {
                    tablet = Tablet(place, date, length, width)
                    thread {
                        tablet!!.id = tabletDao.insertTablet(tablet!!)
                        val imgFileUri = getImage(tablet!!.id.toString())
                        saveImage(tempBitmap, imgFileUri)
                        tablet!!.imgFileUri = imgFileUri
                        tabletDao.updateTablet(tablet!!)
                        activity?.runOnUiThread {
                            showTabletInfo()
                        }
                    }
                }
            })
        }

        /*
        * 点击之后(1)当前点的数据会设置为基准点;
        * */
        binding.lyInfoFragDataMonitor.btnSetBaseDotFragDataMonitor.setOnClickListener {
            if (tablet != null) {
                baseDot = currDot
                baseDot?.let {
                    binding.lyPostureFragDataMonitor.tvBaseRollFragDataMonitor.text = it.attitudeX.toString()
                    binding.lyPostureFragDataMonitor.tvBasePitchFragDataMonitor.text = it.attitudeY.toString()
                    binding.lyPostureFragDataMonitor.tvBaseYawFragDataMonitor.text = it.attitudeY.toString()
                    binding.lyLocationFragDataMonitor.tvBaseLngFragDataMonitor.text = it.locationLng
                    binding.lyLocationFragDataMonitor.tvBaseLatFragDataMonitor.text = it.locationLat
                    binding.lyLocationFragDataMonitor.tvBaseAltFragDataMonitor.text = it.locationAlt
                    binding.lyMagneticIntensityFragDataMonitor.tvBaseXFragDataMonitor.text = it.magneticX.toString()
                    binding.lyMagneticIntensityFragDataMonitor.tvBaseYFragDataMonitor.text = it.magneticY.toString()
                    binding.lyMagneticIntensityFragDataMonitor.tvBaseZFragDataMonitor.text = it.magneticY.toString()
                }
            } else {
                "请选择工程或新建工程".showToast()
            }
        }

        /*
        * 如果基准点不为空，就保存当前点的数据，如果当前点不空，就将当前点数据赋给上个点，并保存当前点
        * */
        binding.lyInfoFragDataMonitor.btnSaveDataFragDataMonitor.setOnClickListener {
            if (tablet != null) {
                val blue = Color.rgb(39, 117, 182)
                if (baseDot != null) {
                    currDot?.let {
                        prevDot = it
                        showPreviousData()
                        thread {
                            dotDao.insertDot(it)
                            activity?.runOnUiThread {
                                binding.lyPostureFragDataMonitor.tvCurrentPitchFragDataMonitor.setTextColor(blue)
                                binding.lyPostureFragDataMonitor.tvCurrentRollFragDataMonitor.setTextColor(blue)
                                binding.lyPostureFragDataMonitor.tvCurrentYawFragDataMonitor.setTextColor(blue)
                                binding.lyLocationFragDataMonitor.tvCurrentAltFragDataMonitor.setTextColor(blue)
                                binding.lyLocationFragDataMonitor.tvCurrentLatFragDataMonitor.setTextColor(blue)
                                binding.lyLocationFragDataMonitor.tvCurrentLngFragDataMonitor.setTextColor(blue)
                                binding.lyMagneticIntensityFragDataMonitor.tvCurrentXFragDataMonitor.setTextColor(blue)
                                binding.lyMagneticIntensityFragDataMonitor.tvCurrentYFragDataMonitor.setTextColor(blue)
                                binding.lyMagneticIntensityFragDataMonitor.tvCurrentZFragDataMonitor.setTextColor(blue)
                            }
                        }
                    }
                } else {
                    "请先设置基准点".showToast()
                }
            } else {
                "请选择工程或新建工程".showToast()
            }
        }

        /*
        * 开始工作，蓝牙配置不正确就提示信息，配置正确就不停的就收数据，并把数据解析，显示出来
        * */
        binding.lyInfoFragDataMonitor.btnStartWorkFragDataMonitor.setOnClickListener {
            if (tablet != null) {
                if (DikeLeakageDetectionApp.currentBleDevice.bleDevice == null
                    || DikeLeakageDetectionApp.currentBleDevice.characteristic == null
                ) {
                    Toast.makeText(DikeLeakageDetectionApp.context, "蓝牙未配置正确", Toast.LENGTH_SHORT).show()
                } else {
                    BleManager.getInstance().notify(
                        DikeLeakageDetectionApp.currentBleDevice.bleDevice,
                        DikeLeakageDetectionApp.currentBleDevice.characteristic!!.service.uuid.toString(),
                        DikeLeakageDetectionApp.currentBleDevice.characteristic!!.uuid.toString(),
                        object : BleNotifyCallback() {
                            override fun onNotifySuccess() {
                                Toast.makeText(
                                    DikeLeakageDetectionApp.context,
                                    "notify success",
                                    Toast.LENGTH_SHORT
                                ).show()
                            }

                            override fun onNotifyFailure(exception: BleException?) {
                                Toast.makeText(
                                    DikeLeakageDetectionApp.context,
                                    "notify failure",
                                    Toast.LENGTH_SHORT
                                ).show()
                            }

                            override fun onCharacteristicChanged(data: ByteArray?) {
                                val string16 =
                                    HexUtil.formatHexString(
                                        DikeLeakageDetectionApp.currentBleDevice.characteristic!!.value,
                                        false
                                    )
                                val s = String(HexUtils.hex2Bytes(string16))
                                showData(s)
                                Log.e("BLE", s)
                                Toast.makeText(DikeLeakageDetectionApp.context, s, Toast.LENGTH_SHORT).show()
                            }

                        }
                    )
                }
            } else {
                "请选择工程或新建工程".showToast()
            }
        }
        return view
    }

    private fun showTabletInfo() {
        binding.lyInfoFragDataMonitor.tvTabletHintFragDataMonitor.visibility = View.GONE
        binding.lyInfoFragDataMonitor.lyTabletInfoFragDataMonitor.visibility = View.VISIBLE
        binding.lyInfoFragDataMonitor.tvTabletPlaceFragDataMonitor.text = tablet?.place
        binding.lyInfoFragDataMonitor.tvTabletDateFragDataMonitor.text = tablet?.date
        binding.lyInfoFragDataMonitor.tvTabletIdFragDataMonitor.text = tablet?.id.toString()
        binding.lyInfoFragDataMonitor.tvTabletLengthFragDataMonitor.text = tablet?.length.toString()
        binding.lyInfoFragDataMonitor.tvTabletWidthFragDataMonitor.text = tablet?.width.toString()
        currDot = Dot(0.0, 0.0, 0.0, 0.0, 0.0, 0.0, "0.0", "0.0", "0.0", tablet!!.id)
    }

    private fun showData(s: String) {
        if (tablet != null) {
            if (MsgUtils.parseMsg(currDot!!, s)) {
                showCurrentData()
            }
            //MsgUtils.parseMsg(s, tablet!!.id)
        } else {
            "请选择工程或新建工程".showToast()
        }
    }

    private fun showPreviousData() {
        prevDot?.let {
            binding.lyLocationFragDataMonitor.tvPrevLngFragDataMonitor.text = it.locationLng
            binding.lyLocationFragDataMonitor.tvPrevLatFragDataMonitor.text = it.locationLat
            binding.lyLocationFragDataMonitor.tvPrevAltFragDataMonitor.text = it.locationAlt
            binding.lyMagneticIntensityFragDataMonitor.tvPrevXFragDataMonitor.text = it.magneticX.toString()
            binding.lyMagneticIntensityFragDataMonitor.tvPrevYFragDataMonitor.text = it.magneticY.toString()
            binding.lyMagneticIntensityFragDataMonitor.tvPrevZFragDataMonitor.text = it.magneticZ.toString()
        }

    }

    private fun showCurrentData() {
        currDot?.let {
            binding.lyPostureFragDataMonitor.tvCurrentRollFragDataMonitor.text = it.attitudeX.toString()
            binding.lyPostureFragDataMonitor.tvCurrentPitchFragDataMonitor.text = it.attitudeY.toString()
            binding.lyPostureFragDataMonitor.tvCurrentYawFragDataMonitor.text = it.attitudeZ.toString()
            binding.lyLocationFragDataMonitor.tvCurrentLngFragDataMonitor.text = it.locationLng
            binding.lyLocationFragDataMonitor.tvCurrentLatFragDataMonitor.text = it.locationLat
            binding.lyLocationFragDataMonitor.tvCurrentAltFragDataMonitor.text = it.locationAlt
            binding.lyMagneticIntensityFragDataMonitor.tvCurrentXFragDataMonitor.text = it.magneticX.toString()
            binding.lyMagneticIntensityFragDataMonitor.tvCurrentYFragDataMonitor.text = it.magneticY.toString()
            binding.lyMagneticIntensityFragDataMonitor.tvCurrentZFragDataMonitor.text = it.magneticZ.toString()

            val gray = Color.rgb(47, 47, 53)

            binding.lyPostureFragDataMonitor.tvCurrentPitchFragDataMonitor.setTextColor(gray)
            binding.lyPostureFragDataMonitor.tvCurrentRollFragDataMonitor.setTextColor(gray)
            binding.lyPostureFragDataMonitor.tvCurrentYawFragDataMonitor.setTextColor(gray)
            binding.lyLocationFragDataMonitor.tvCurrentAltFragDataMonitor.setTextColor(gray)
            binding.lyLocationFragDataMonitor.tvCurrentLatFragDataMonitor.setTextColor(gray)
            binding.lyLocationFragDataMonitor.tvCurrentLngFragDataMonitor.setTextColor(gray)
            binding.lyMagneticIntensityFragDataMonitor.tvCurrentXFragDataMonitor.setTextColor(gray)
            binding.lyMagneticIntensityFragDataMonitor.tvCurrentYFragDataMonitor.setTextColor(gray)
            binding.lyMagneticIntensityFragDataMonitor.tvCurrentZFragDataMonitor.setTextColor(gray)
        }
    }

}